package com.wizitsoft.com.lab.ast;

import org.codehaus.groovy.transform.ASTTransformation;
import org.codehaus.groovy.transform.GroovyASTTransformation;
import org.codehaus.groovy.control.CompilePhase;
import org.codehaus.groovy.ast.ClassNode;
import org.codehaus.groovy.control.SourceUnit;
import org.codehaus.groovy.ast.ASTNode;
import org.codehaus.groovy.ast.AnnotationNode;
import org.codehaus.groovy.ast.AnnotatedNode;

@GroovyASTTransformation(phase = CompilePhase.CANONICALIZATION)
public class DomainExtASTTransformation implements ASTTransformation {

private static final Class<DomainExt> MY_CLASS = DomainExt.class;
    private static final ClassNode MY_TYPE = new ClassNode(MY_CLASS);
    private static final String MY_TYPE_NAME = "@" + MY_TYPE.getNameWithoutPackage();

    public void visit(ASTNode[] astNodes, SourceUnit sourceUnit) {
		System.out.println("com.wizitsoft.com.lab.ast.DomainExtASTTransformation starting...");

        if (!(astNodes[0] instanceof AnnotationNode) || !(astNodes[1] instanceof AnnotatedNode)) {
            throw new RuntimeException("Internal error: wrong types: $node.class / $parent.class");
        }
        AnnotatedNode parent = (AnnotatedNode) astNodes[1];
        AnnotationNode node = (AnnotationNode) astNodes[0];
        if (!MY_TYPE.equals(node.getClassNode())) return;
        if(parent instanceof ClassNode) {
            ClassNode cNode = (ClassNode) parent;
            String cName = cNode.getName();
            if (cNode.isInterface()) {
                throw new RuntimeException("Error processing interface '" + cName + "'. " + MY_TYPE_NAME + " not allowed for interfaces.");
            }
            System.out.println("cName: " + cName);
            DomainExtClassInjector injector = new DomainExtClassInjector();
            injector.performInjectionOnDomainExt(cNode);
        }

		System.out.println("com.wizitsoft.com.lab.ast.DomainExtASTTransformation finish.");
	}
}